package org.infodavid.common.scheduler.impl;

import java.io.InputStream;
import java.sql.Connection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.infodavid.common.persistence.SqlScriptHelper;
import org.infodavid.common.persistence.impl.PersistenceUtil;
import org.infodavid.common.scheduler.PersistenceHelper;

public class PersistenceHelperImpl extends PersistenceHelper {
	/** The Constant log. */
	private static final Log LOGGER = LogFactory.getLog(PersistenceHelperImpl.class);

	/** The Constant INIT_SCRIPT_PREFIX. */
	public static final String INIT_SCRIPT_PREFIX = "/scheduler_tables_";

	/** The Constant INIT_SCRIPT_SUFFIX. */
	public static final String INIT_SCRIPT_SUFFIX = ".sql";

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.scheduler.PersistenceHelper#initializeDataSource(java.lang.String)
	 */
	public void initializeDataSource(final String jndiName) throws Exception {
		Connection connection = null;
		InputStream input = null;

		try {
			LOGGER.info("Checking database schema...");

			connection = PersistenceUtil.getJndiConnection(jndiName);
			connection.setAutoCommit(false);

			final String dbType = connection.getMetaData().getDatabaseProductName().toLowerCase();

			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("Scheduler database type is " + dbType);
				LOGGER.debug("Loading SQL script: " + INIT_SCRIPT_PREFIX + dbType + INIT_SCRIPT_SUFFIX);
			}

			input = getClass().getResourceAsStream(INIT_SCRIPT_PREFIX + dbType + INIT_SCRIPT_SUFFIX);

			final SqlScriptHelper helper = SqlScriptHelper.getInstance();
			final String[] lines = helper.parse(input);

			helper.execute(connection, lines);
			connection.commit();
		}
		catch (final Exception e) {
			if (connection != null) {
				try {
					connection.rollback();
				}
				catch (final Exception e2) {
					LOGGER.debug("An error occurs while rolling back the transaction", e);
				}
			}

			throw e;
		}
		finally {
			if (input != null) {
				try {
					input.close();
				}
				catch (final Exception e) {
					LOGGER.debug("An error occurs while closing the input stream on properties file", e);
				}
			}

			if (connection != null) {
				try {
					connection.close();
				}
				catch (final Exception e) {
					LOGGER.debug("An error occurs while closing connection", e);
				}
			}
		}
	}
}
